package cn.hamster3.mc.plugin.ball.bukkit;

import cn.hamster3.mc.plugin.ball.bukkit.api.BallBukkitAPI;
import cn.hamster3.mc.plugin.ball.bukkit.hook.PlaceholderHook;
import cn.hamster3.mc.plugin.ball.bukkit.listener.BallBukkitListener;
import cn.hamster3.mc.plugin.ball.bukkit.listener.UpdatePlayerInfoListener;
import cn.hamster3.mc.plugin.ball.bukkit.util.BallBukkitUtils;
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;

public class HamsterBallPlugin extends JavaPlugin {
    @Getter
    private static HamsterBallPlugin instance;

    public static void sync(@NotNull Runnable runnable) {
        Bukkit.getScheduler().runTask(instance, runnable);
    }

    public static void async(@NotNull Runnable runnable) {
        Bukkit.getScheduler().runTaskAsynchronously(instance, runnable);
    }

    @Override
    public void onLoad() {
        long start = System.currentTimeMillis();
        Logger logger = getLogger();
        logger.info("仓鼠球正在初始化");
        instance = this;
        saveDefaultConfig();
        reloadConfig();
        logger.info("已读取配置文件");
        try {
            File dataFolder = getDataFolder();
            if (dataFolder.mkdir()) {
                logger.info("已生成插件存档文件夹");
            }
            File configFile = new File(dataFolder, "config.yml");
            if (!configFile.exists()) {
                Files.copy(
                        Objects.requireNonNull(getResource("config.yml")),
                        configFile.toPath(),
                        StandardCopyOption.REPLACE_EXISTING
                );
            }
            BallBukkitAPI.init(configFile);
            logger.info("已初始化 BallAPI");
        } catch (Exception e) {
            logger.log(Level.SEVERE, "BallAPI 初始化失败", e);
            Bukkit.shutdown();
            return;
        }
        long time = System.currentTimeMillis() - start;
        logger.info("仓鼠球初始化完成，总计耗时 " + time + " ms");
    }

    @Override
    public void onEnable() {
        long start = System.currentTimeMillis();
        Logger logger = getLogger();
        logger.info("仓鼠球正在启动");
        try {
            BallBukkitAPI.getInstance().enable();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "仓鼠球启动失败", e);
            logger.info("由于仓鼠球启动失败，服务器将立即关闭");
            Bukkit.shutdown();
            return;
        }
        Bukkit.getPluginManager().registerEvents(BallBukkitListener.INSTANCE, this);
        BallAPI.getInstance().getEventBus().register(BallBukkitListener.INSTANCE);
        logger.info("已注册监听器 BallBukkitListener");
        if (BallAPI.getInstance().getBallConfig().isGameServerUpdatePlayerInfo()) {
            BallAPI.getInstance().subscribe(BallAPI.PLAYER_INFO_CHANNEL);
            Bukkit.getPluginManager().registerEvents(UpdatePlayerInfoListener.INSTANCE, this);
            BallAPI.getInstance().getEventBus().register(UpdatePlayerInfoListener.INSTANCE);
            logger.info("已注册监听器 UpdatePlayerInfoListener");

            // 移除失效的在线玩家
            BallAPI.getInstance().getAllPlayerInfo().values()
                    .stream()
                    .filter(BallPlayerInfo::isOnline)
                    .filter(o -> BallAPI.getInstance().isLocalServer(o.getGameServer()))
                    .forEach(playerInfo -> {
                        playerInfo.setOnline(false);
                        BallBukkitUtils.uploadPlayerInfo(playerInfo);
                    });
        } else {
            BallAPI.getInstance().subscribeIgnorePrefix(BallAPI.PLAYER_INFO_CHANNEL);
        }
        sync(() -> {
            if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
                PlaceholderHook.INSTANCE.register();
                logger.info("已挂载 PlaceholderAPI 变量");
            }
            BallAPI.getInstance().sendRawBallMessage(
                    BallAPI.BALL_CHANNEL, BallActions.ServerOnline.name(),
                    new ServerOnlineEvent(BallAPI.getInstance().getLocalServerInfo())
            );
        });
        long time = System.currentTimeMillis() - start;
        logger.info("仓鼠球启动完成，总计耗时 " + time + " ms");
    }

    @Override
    public void onDisable() {
        long start = System.currentTimeMillis();
        Logger logger = getLogger();
        logger.info("仓鼠球正在关闭");
        try {
            BallBukkitAPI.getInstance().disable();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "关闭仓鼠球时遇到了一个异常", e);
        }
        long time = System.currentTimeMillis() - start;
        logger.info("仓鼠球已关闭，总计耗时 " + time + " ms");
    }
}
